package cn.iocoder.yudao.module.erp.service.recycle.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.erp.controller.admin.recycle.vo.item.ErpRecycleOrderItemBaseVO;
import cn.iocoder.yudao.module.erp.controller.admin.recycle.vo.order.ErpRecycleOrderCreateReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.recycle.vo.order.ErpRecycleOrderPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.recycle.vo.order.ErpRecycleOrderUpdateReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.recycle.ErpRecycleOrderDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.recycle.ErpRecycleOrderItemDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpCustomerDO;
import cn.iocoder.yudao.module.erp.dal.mysql.recycle.ErpRecycleOrderItemMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.recycle.ErpRecycleOrderMapper;
import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
import cn.iocoder.yudao.module.erp.service.recycle.ErpRecycleOrderService;
import cn.iocoder.yudao.module.erp.service.sale.ErpCustomerService;
import cn.iocoder.yudao.module.erp.service.stock.ErpStockService;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;

/**
 * ERP 回收订单 Service 实现类
 */
@Service
@Validated
@Slf4j
public class ErpRecycleOrderServiceImpl implements ErpRecycleOrderService {

    private static final String ORDER_NO_PREFIX = "RC";

    @Resource
    private ErpRecycleOrderMapper recycleOrderMapper;
    @Resource
    private ErpRecycleOrderItemMapper recycleOrderItemMapper;

    @Resource
    private ErpCustomerService customerService;
    @Resource
    private ErpProductService productService;
    @Resource
    private ErpStockService stockService;
    @Resource
    private AdminUserApi adminUserApi;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createRecycleOrder(ErpRecycleOrderCreateReqVO createReqVO) {
        // 1. 校验客户
        ErpCustomerDO customer = customerService.getCustomer(createReqVO.getCustomerId());
        if (customer == null) {
            throw exception(CUSTOMER_NOT_EXISTS);
        }
        if (ObjectUtil.notEqual(customer.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
            throw exception(CUSTOMER_NOT_ENABLE, customer.getName());
        }

        // 2. 生成订单流水号
        String no = ORDER_NO_PREFIX + LocalDateTime.now().toString();
        // TODO: 基于redis自增生成编号

        // 3. 校验产品，计算金额
        List<ErpRecycleOrderItemDO> recycleOrderItems = validateProductItems(createReqVO.getItems());

        // 4. 保存订单
        ErpRecycleOrderDO recycleOrder = BeanUtils.toBean(createReqVO, ErpRecycleOrderDO.class);
        recycleOrder.setNo(no);
        recycleOrder.setStatus(ErpAuditStatus.DRAFT.getStatus());
        recycleOrder.setCustomerName(customer.getName());
        recycleOrderMapper.insert(recycleOrder);

        // 5. 保存订单项
        for (ErpRecycleOrderItemDO item : recycleOrderItems) {
            item.setOrderId(recycleOrder.getId());
            recycleOrderItemMapper.insert(item);
        }
        return recycleOrder.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateRecycleOrder(ErpRecycleOrderUpdateReqVO updateReqVO) {
        // 1.1 校验存在
        ErpRecycleOrderDO recycleOrder = validateRecycleOrderExists(updateReqVO.getId());
        // 1.2 校验状态
        if (ObjectUtil.notEqual(recycleOrder.getStatus(), ErpAuditStatus.DRAFT.getStatus())) {
            throw exception(RECYCLE_ORDER_UPDATE_FAIL_APPROVE, recycleOrder.getNo());
        }

        // 2. 校验客户
        ErpCustomerDO customer = customerService.getCustomer(updateReqVO.getCustomerId());
        if (customer == null) {
            throw exception(CUSTOMER_NOT_EXISTS);
        }
        if (ObjectUtil.notEqual(customer.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
            throw exception(CUSTOMER_NOT_ENABLE, customer.getName());
        }

        // 3. 校验产品，计算金额
        List<ErpRecycleOrderItemDO> recycleOrderItems = validateProductItems(updateReqVO.getItems());

        // 4. 更新订单
        ErpRecycleOrderDO updateObj = BeanUtils.toBean(updateReqVO, ErpRecycleOrderDO.class);
        updateObj.setCustomerName(customer.getName());
        recycleOrderMapper.updateById(updateObj);

        // 5.1 删除旧的订单项
        recycleOrderItemMapper.deleteByOrderId(updateReqVO.getId());
        // 5.2 插入新的订单项
        for (ErpRecycleOrderItemDO item : recycleOrderItems) {
            item.setOrderId(updateReqVO.getId());
            recycleOrderItemMapper.insert(item);
        }
    }

    @Override
    public void updateRecycleOrderStatus(Long id, Integer status) {
        // 校验存在
        ErpRecycleOrderDO recycleOrder = validateRecycleOrderExists(id);
        // 更新状态
        recycleOrderMapper.updateById(new ErpRecycleOrderDO().setId(id).setStatus(status));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteRecycleOrder(Long id) {
        // 1.1 校验存在
        ErpRecycleOrderDO recycleOrder = validateRecycleOrderExists(id);
        // 1.2 校验状态
        if (ObjectUtil.notEqual(recycleOrder.getStatus(), ErpAuditStatus.DRAFT.getStatus())) {
            throw exception(RECYCLE_ORDER_DELETE_FAIL_APPROVE, recycleOrder.getNo());
        }

        // 2. 删除
        recycleOrderMapper.deleteById(id);
        recycleOrderItemMapper.deleteByOrderId(id);
    }

    @Override
    public ErpRecycleOrderDO getRecycleOrder(Long id) {
        return recycleOrderMapper.selectById(id);
    }

    @Override
    public List<ErpRecycleOrderDO> getRecycleOrderList(Collection<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return Collections.emptyList();
        }
        return recycleOrderMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<ErpRecycleOrderDO> getRecycleOrderPage(ErpRecycleOrderPageReqVO pageReqVO) {
        return recycleOrderMapper.selectPage(pageReqVO);
    }

    @Override
    public List<ErpRecycleOrderItemDO> getRecycleOrderItemListByOrderId(Long orderId) {
        return recycleOrderItemMapper.selectListByOrderId(orderId);
    }

    @Override
    public List<ErpRecycleOrderItemDO> getRecycleOrderItemListByOrderId(Collection<Long> orderIds) {
        if (CollUtil.isEmpty(orderIds)) {
            return Collections.emptyList();
        }
        return recycleOrderItemMapper.selectListByOrderIds(orderIds);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void approveRecycleOrder(Long id) {
        // 1.1 校验存在
        ErpRecycleOrderDO recycleOrder = validateRecycleOrderExists(id);
        // 1.2 校验状态
        if (ObjectUtil.notEqual(recycleOrder.getStatus(), ErpAuditStatus.DRAFT.getStatus())) {
            throw exception(RECYCLE_ORDER_APPROVE_FAIL);
        }

        // 2. 更新状态
//        recycleOrderMapper.updateById(new ErpRecycleOrderDO().setId(id)
//                .setStatus(ErpAuditStatus.APPROVED.getStatus())
//                .setApproveBy(adminUserApi.getUser(adminUserApi.getLoginUserId()).getNickname())
//                .setApproveTime(LocalDateTime.now()));

        // 3. 更新库存
        // 3.1 查询订单项
        List<ErpRecycleOrderItemDO> items = recycleOrderItemMapper.selectListByOrderId(id);
        if (CollUtil.isEmpty(items)) {
            return;
        }
        
        // 3.2 更新库存 - 入库
//        for (ErpRecycleOrderItemDO item : items) {
//            stockService.updateStockCount(item.getProductId(), null,
//                    item.getCount(), ErpBizTypeEnum.RECYCLE_IN.getType(), String.valueOf(id));
//        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void disapproveRecycleOrder(Long id) {
        // 1.1 校验存在
        ErpRecycleOrderDO recycleOrder = validateRecycleOrderExists(id);
        // 1.2 校验状态
//        if (ObjectUtil.notEqual(recycleOrder.getStatus(), ErpAuditStatus.APPROVED.getStatus())) {
//            throw exception(RECYCLE_ORDER_PROCESS_FAIL);
//        }

        // 2. 更新状态
        recycleOrderMapper.updateById(new ErpRecycleOrderDO().setId(id)
                .setStatus(ErpAuditStatus.DRAFT.getStatus())
                .setApproveBy(null).setApproveTime(null));

        // 3. 回滚库存
        // 3.1 查询订单项
        List<ErpRecycleOrderItemDO> items = recycleOrderItemMapper.selectListByOrderId(id);
        if (CollUtil.isEmpty(items)) {
            return;
        }
        
        // 3.2 更新库存 - 出库（回滚）
//        for (ErpRecycleOrderItemDO item : items) {
//            stockService.updateStockCount(item.getProductId(), null,
//                    item.getCount().negate(), ErpBizTypeEnum.RECYCLE_IN.getType(), String.valueOf(id));
//        }
    }

    /**
     * 校验回收订单是否存在
     *
     * @param id 订单编号
     * @return 回收订单
     */
    private ErpRecycleOrderDO validateRecycleOrderExists(Long id) {
        ErpRecycleOrderDO recycleOrder = recycleOrderMapper.selectById(id);
        if (recycleOrder == null) {
            throw exception(RECYCLE_ORDER_NOT_EXISTS);
        }
        return recycleOrder;
    }

    /**
     * 校验产品项目
     *
     * @param items 产品项目列表
     * @return 订单项列表
     */
    private List<ErpRecycleOrderItemDO> validateProductItems(List<ErpRecycleOrderItemBaseVO> items) {
        // 1. 转换成 DO 对象
        List<ErpRecycleOrderItemDO> itemDOs = BeanUtils.toBean(items, ErpRecycleOrderItemDO.class);

        // 2. 校验产品存在
//        Map<Long, ErpProductDO> productMap = productService.getProductMap(
//                CollectionUtils.convertSet(items, ErpRecycleOrderItemDO::getProductId));
        
        // 3. 遍历处理每个项目
        BigDecimal totalPrice = BigDecimal.ZERO;
        BigDecimal totalWeight = BigDecimal.ZERO;
//        for (int i = 0; i < itemDOs.size(); i++) {
//            ErpRecycleOrderItemDO item = itemDOs.get(i);
//            // 3.1 校验产品
//            ErpProductDO product = productMap.get(item.getProductId());
//            if (product == null) {
//                throw exception(PRODUCT_NOT_EXISTS);
//            }
//            if (ObjectUtil.notEqual(product.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
//                throw exception(PRODUCT_NOT_ENABLE, product.getName());
//            }
//            // 校验是否支持回收
//            if (ObjectUtil.notEqual(product.getRecyclable(), CommonStatusEnum.ENABLE.getStatus())) {
//                throw exception(new ErrorCode(1030300100, "产品({})不支持回收", product.getName()));
//            }
//
//            // 3.2 设置排序
//            item.setSort(i);
//
//            // 3.3 累计总金额
//            totalPrice = MoneyUtils.add(totalPrice, item.getPrice());
//            totalWeight = MoneyUtils.add(totalWeight, item.getWeight());
//        }
        
        return itemDOs;
    }
} 